<script setup>
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(95, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

//定义一个cubeArr用来存储多个cube
let cubeArr = []
function createCube () {
  let list = []
  for (let i = 0; i < 10; i++) {
    list.push({
      col: `rgb(${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`,
      width: Math.floor(Math.random() * (3 - 1 + 1) + 1),
      height: Math.floor(Math.random() * (3 - 1 + 1) + 1),
      deep: Math.floor(Math.random() * (3 - 1 + 1) + 1),
      x: Math.floor(Math.random() * (5 - 1 + 1) + -5),
      y: Math.floor(Math.random() * (5 - 1 + 1) + -5),
      z: Math.floor(Math.random() * (5 - 1 + 1) + -5),
    })
  }

  list.forEach(({ col, width, height, deep, x, y, z }) => {
    const geometry = new THREE.BoxGeometry(width, height, deep);
    const material = new THREE.MeshBasicMaterial({ color: col });
    const cube = new THREE.Mesh(geometry, material);
    cube.position.set(x, y, z)
    scene.add(cube);
    cubeArr.push(cube)

  })
}


//目标：借助光线投射的技术与3D物体进行鼠标交互
const bindDBClick = () => {
  //1、光线投射对象
  const raycaster = new THREE.Raycaster();
  //2、坐标转换
  const pointer = new THREE.Vector2();
  //双击事件
  window.addEventListener('dblclick', (event) => {
    // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
    //屏幕坐标 =》 webGL设备坐标(公式)
    pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
    pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
    //产生射线
    raycaster.setFromCamera(pointer, camera)
    // 4、手机射线穿越过的物体
    //参数：要让摄像机到鼠标点传过去一条线，与哪些3D物体交互计算
    //list 手机到你点过的物体们(数组)-顺序是按照由近到远
    //scene.children世界当中所有孩子物体的集合数组
    //cubeArr 物体数组
    const list = raycaster.intersectObjects(cubeArr)

    //点到了立方体 list数组才有值
    if (list.length > 0) {
      const cube = list[0].object //.object才是3D物体

      // ========================================================================
      //一下是收集到物体的坐标具体根据需求处理的逻辑 
      //没有颠倒立方体
      if (!cube) return

      cube.geometry.dispose()
      cube.material.dispose()
      scene.remove(cube)
      // cubeArr.shift()
      //==============================================================================
    }

  })
}





//创建一个坐标轴
function createAxes () {
  const axesHelper = new THREE.AxesHelper(5)
  scene.add(axesHelper)
}





//适配画布大小
function resize () {
  window.addEventListener('resize', () => {
    renderer.setSize(window.innerWidth, window.innerHeight)
    //重新根据响应改变物体的宽高比
    camera.aspect = window.innerWidth / window.innerHeight
    //更新摄像机矩阵空间(让摄像机重新计算每个像素点位置和大小)
    camera.updateProjectionMatrix()
  })
}


//创建轨道控制器
//轨道控制器（控制摄像机位置 ）
let controls
function createOrbit () {
  controls = new OrbitControls(camera, renderer.domElement)
  controls.update()
}
function animate () {
  requestAnimationFrame(animate)
  controls.update();
  renderer.render(scene, camera)
}

//调用创建坐标轴
createAxes()

createOrbit()
resize()
createCube()
bindDBClick()
animate()
renderer.render(scene, camera)


</script>

<template></template>

<style scoped>
</style>
